<%- # the license inside this block applies to this file
# Copyright 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-%>
<%# NOTE NOTE NOTE
    The newlines in this file are *load bearing*.  This file outputs
    Markdown, which is extremely sensitive to newlines.  You have got
    to have a newline after every attribute and property, because
    otherwise MD will think the next element is part of the previous
    property's bullet point.  You cannot have any double newlines in the
    middle of a property or attribute, because MD will think that the
    empty line ends the bullet point and the indentation will be off.
    You must have a newline before and after all --- document indicators,
    and you must have a newline before and after all - - - hlines.
    You cannot have more than one blank line between properties.
    The --- document indicator must be the first line of the file.
    As long as you only use `build_property_documentation`, it all works
    fine - but when you need to add custom docs (notes, etc), you need
    to remember these things.

    Know also that the `lines` function in heavy use in MagicModules will
    strip exactly one trailing newline - unless that's what you've designed
    your docstring for, it's easier to insert newlines where you need them
    manually.  That's why, in this file, we use `lines` on anything which
    is generated from a ruby function, but skip it on anything that is
    directly inserted from YAML.
-%>
<%
  tf_product = (@config.legacy_name || product_ns).underscore
  product_ns_display = (@config.legacy_name || product_ns).camelize
  tf_subcategory = (object.__product.display_name)
  resource_ns = object.legacy_name || "google_#{tf_product}_#{object.name.underscore}"
  resource_ns_iam = "#{resource_ns}_iam"
  properties = object.all_user_properties

  # In order of preference, use TF override,
  # general defined timeouts, or default Timeouts
  timeouts = object.timeouts
  timeouts ||= object&.async&.operation&.timeouts
  timeouts ||= Api::Timeouts.new
-%>
---
<%= lines(autogen_notice(:yaml, pwd)) -%>
subcategory: "<%= tf_subcategory -%>"
layout: "google"
page_title: "Google: <%= resource_ns_iam -%>"
sidebar_current: "docs-<%= resource_ns_iam.gsub("_", "-") -%>"
description: |-
  Collection of resources to manage IAM policy for <%= product.display_name -%> <%= object.name %>
---

# IAM policy for <%= product.display_name -%> <%= object.name %>
Three different resources help you manage your IAM policy for <%= product.display_name -%> <%= object.name -%>. Each of these resources serves a different use case:

* `<%= resource_ns_iam -%>_policy`: Authoritative. Sets the IAM policy for the <%= object.name.downcase -%> and replaces any existing policy already attached.
* `<%= resource_ns_iam -%>_binding`: Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the <%= object.name.downcase -%> are preserved.
* `<%= resource_ns_iam -%>_member`: Non-authoritative. Updates the IAM policy to grant a role to a new member. Other members for the role for the <%= object.name.downcase -%> are preserved.

~> **Note:** `<%= resource_ns_iam -%>_policy` **cannot** be used in conjunction with `<%= resource_ns_iam -%>_binding` and `<%= resource_ns_iam -%>_member` or they will fight over what your policy should be.

~> **Note:** `<%= resource_ns_iam -%>_binding` resources **can be** used in conjunction with `<%= resource_ns_iam -%>_member` resources **only if** they do not grant privilege to the same role.

<% unless version == 'ga' || object.iam_policy.iam_conditions_request_type.nil? -%>
~> **Note:**  This resource supports IAM Conditions ([beta](https://terraform.io/docs/providers/google/provider_versions.html)) but they have some known limitations which can be found [here](https://cloud.google.com/iam/docs/conditions-overview#limitations). Please review this article if you are having issues with IAM Conditions.
<% end -%>

<% if object.min_version.name == 'beta' -%>
~> **Warning:** This resource is in beta, and should be used with the terraform-provider-google-beta provider.
See [Provider Versions](https://terraform.io/docs/providers/google/guides/provider_versions.html) for more details on beta resources.
<% end -%>

<% markdown_escaped_name = resource_ns_iam.gsub("_", "\\_") %>
<% params = extract_identifiers(object.iam_policy.self_link || object.self_link_url) -%>
<%
url_properties = object.all_user_properties.select do
  |param| params.include?(param.name)
end
-%>
## <%= markdown_escaped_name -%>\_policy

```hcl
data "google_iam_policy" "admin" {
  binding {
    role = "<%= object.iam_policy.admin_iam_role || object.iam_policy.allowed_iam_role -%>"
    members = [
      "user:jane@example.com",
    ]
  }
}

resource "<%= resource_ns_iam -%>_policy" "policy" {
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  policy_data = data.google_iam_policy.admin.policy_data
}
```

<% unless version == 'ga' || object.iam_policy.iam_conditions_request_type.nil? -%>
With IAM Conditions ([beta](https://terraform.io/docs/providers/google/provider_versions.html)):

```hcl
data "google_iam_policy" "admin" {
  binding {
    role = "<%= object.iam_policy.admin_iam_role || object.iam_policy.allowed_iam_role -%>"
    members = [
      "user:jane@example.com",
    ]

    condition {
      title       = "expires_after_2019_12_31"
      description = "Expiring at midnight of 2019-12-31"
      expression  = "request.time < timestamp(\"2020-01-01T00:00:00Z\")"
    }
  }
}

resource "<%= resource_ns_iam -%>_policy" "policy" {
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  policy_data = data.google_iam_policy.admin.policy_data
}
```
<% end -%>
## <%= markdown_escaped_name -%>\_binding

```hcl
resource "<%= resource_ns_iam -%>_binding" "binding" {
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "<%= object.iam_policy.admin_iam_role || object.iam_policy.allowed_iam_role -%>"
  members = [
    "user:jane@example.com",
  ]
}
```

<% unless version == 'ga' || object.iam_policy.iam_conditions_request_type.nil? -%>
With IAM Conditions ([beta](https://terraform.io/docs/providers/google/provider_versions.html)):

```hcl
resource "<%= resource_ns_iam -%>_binding" "binding" {
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "<%= object.iam_policy.admin_iam_role || object.iam_policy.allowed_iam_role -%>"
  members = [
    "user:jane@example.com",
  ]

  condition {
    title       = "expires_after_2019_12_31"
    description = "Expiring at midnight of 2019-12-31"
    expression  = "request.time < timestamp(\"2020-01-01T00:00:00Z\")"
  }
}
```
<% end -%>
## <%= markdown_escaped_name -%>\_member

```hcl
resource "<%= resource_ns_iam -%>_member" "member" {
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "<%= object.iam_policy.admin_iam_role || object.iam_policy.allowed_iam_role -%>"
  member = "user:jane@example.com"
}
```

<% unless version == 'ga' || object.iam_policy.iam_conditions_request_type.nil? -%>
With IAM Conditions ([beta](https://terraform.io/docs/providers/google/provider_versions.html)):

```hcl
resource "<%= resource_ns_iam -%>_member" "member" {
<%= lines(compile(pwd + '/' + object.iam_policy.example_config_body)) -%>
  role = "<%= object.iam_policy.admin_iam_role || object.iam_policy.allowed_iam_role -%>"
  member = "user:jane@example.com"

  condition {
    title       = "expires_after_2019_12_31"
    description = "Expiring at midnight of 2019-12-31"
    expression  = "request.time < timestamp(\"2020-01-01T00:00:00Z\")"
  }
}
```
<% end -%>
## Argument Reference

The following arguments are supported:

<% url_properties.each do |param| -%>
<% if param.name == "name" -%>
* `<%= object.iam_policy.parent_resource_attribute || object.name.underscore -%>` - (Required) Used to find the parent resource to bind the IAM policy to
<% elsif ["region", "zone"].include?(param.name.underscore) -%>
* `<%= param.name.underscore -%>` - (Optional) <%= param.description -%> Used to find the parent resource to bind the IAM policy to. If not specified,
  the value will be parsed from the identifier of the parent resource. If no <%= param.name.underscore -%> is provided in the parent identifier and no
  <%= param.name.underscore -%> is specified, it is taken from the provider configuration.
<% else -%>
* `<%= param.name.underscore -%>` - (Required) <%= param.description -%> Used to find the parent resource to bind the IAM policy to
<% end -%>
<% end -%>
<% if object.base_url.include?("{{project}}")-%>
<%# The following new line allow for project to be bullet-formatted properly. -%>

* `project` - (Optional) The ID of the project in which the resource belongs.
    If it is not provided, the project will be parsed from the identifier of the parent resource. If no project is provided in the parent identifier and no project is specified, the provider project is used.
<% end -%>

* `member/members` - (Required) Identities that will be granted the privilege in `role`.
  Each entry can have one of the following values:
  * **allUsers**: A special identifier that represents anyone who is on the internet; with or without a Google account.
  * **allAuthenticatedUsers**: A special identifier that represents anyone who is authenticated with a Google account or a service account.
  * **user:{emailid}**: An email address that represents a specific Google account. For example, alice@gmail.com or joe@example.com.
  * **serviceAccount:{emailid}**: An email address that represents a service account. For example, my-other-app@appspot.gserviceaccount.com.
  * **group:{emailid}**: An email address that represents a Google group. For example, admins@example.com.
  * **domain:{domain}**: A G Suite domain (primary, instead of alias) name that represents all the users of that domain. For example, google.com or example.com.

* `role` - (Required) The role that should be applied. Only one
    `<%= resource_ns_iam -%>_binding` can be used per role. Note that custom roles must be of the format
    `[projects|organizations]/{parent-name}/roles/{role-name}`.

* `policy_data` - (Required only by `<%= resource_ns_iam -%>_policy`) The policy data generated by
  a `google_iam_policy` data source.

<% unless version == 'ga' || object.iam_policy.iam_conditions_request_type.nil? -%>
* `condition` - (Optional, [Beta](https://terraform.io/docs/providers/google/provider_versions.html)) An [IAM Condition](https://cloud.google.com/iam/docs/conditions-overview) for a given binding.
  Structure is documented below.

---

The `condition` block supports:

* `expression` - (Required) Textual representation of an expression in Common Expression Language syntax.

* `title` - (Required) A title for the expression, i.e. a short string describing its purpose.

* `description` - (Optional) An optional description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI.

~> **Warning:** Terraform considers the `role` and condition contents (`title`+`description`+`expression`) as the
  identifier for the binding. This means that if any part of the condition is changed out-of-band, Terraform will
  consider it to be an entirely different resource and will treat it as such.
<% end -%>
## Attributes Reference

In addition to the arguments listed above, the following computed attributes are
exported:

* `etag` - (Computed) The etag of the IAM policy.

## Import

For all import syntaxes, the "resource in question" can take any of the following forms:
<% import_format = object.iam_policy.import_format || object.import_format -%>
<% all_formats = import_id_formats(import_format, object.identity, object.base_url).map{ |id| id.gsub('%', '') } -%>

<% all_formats.each do |id_format| -%>
* <%= id_format %>
<% end -%>

Any variables not passed in the import command will be taken from the provider configuration.

<%= product.display_name -%> <%= object.name.downcase -%> IAM resources can be imported using the resource identifiers, role, and member.

IAM member imports use space-delimited identifiers: the resource in question, the role, and the member identity, e.g.
```
$ terraform import <%= resource_ns_iam -%>_member.editor "<%= all_formats.first.gsub('{{name}}', "{{#{object.name.underscore}}}") -%> <%= object.iam_policy.allowed_iam_role -%> user:jane@example.com"
```

IAM binding imports use space-delimited identifiers: the resource in question and the role, e.g.
```
$ terraform import <%= resource_ns_iam -%>_binding.editor "<%= all_formats.first.gsub('{{name}}', "{{#{object.name.underscore}}}") -%> <%= object.iam_policy.allowed_iam_role -%>"
```

IAM policy imports use the identifier of the resource in question, e.g.
```
$ terraform import <%= resource_ns_iam -%>_policy.editor <%= all_formats.first.gsub('{{name}}', "{{#{object.name.underscore}}}") %>
```

-> **Custom Roles**: If you're importing a IAM resource with a custom role, make sure to use the
 full name of the custom role, e.g. `[projects/my-project|organizations/my-org]/roles/my-custom-role`.

<% if object.base_url.include?("{{project}}")-%>
## User Project Overrides

This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override).
<% end -%>
